import React, {useState, useEffect, useCallback} from 'react';
import { SearchOutlined } from '@ant-design/icons';
import { Input, message } from 'antd';
import { Tooltip } from 'antd';
import classnames from 'classnames/bind';
import PropTypes from 'prop-types';
import memo from '../../common/wrapMemo';
import {centerOfMass, polygon} from '@turf/turf';

import { polygonColorMap } from '../../../constant/layers';
import api from '../../../api/index';

import SearchResult from './SearchResult';

import style from './Search.module.scss';

const cb = classnames.bind(style);
const { Search } = Input;
const { L } = window;
const { BASE_URL } = window.CONFIG;

// let layerArr = [];
let inputValue = '';
let pointLayer = null;
let polygonLayer = null;

// 面高亮图层
let polygonHighLayer = null;

// 面高亮样式配置
const highStyleOption = {
    weight: 2,
    opacity: 1,
    color: 'blue',
    fillOpacity: 0.2,
    fillColor: 'blue'
};

let center = [];
let firstInit = false;
const filterKeys = ['geom','geojson', 'gid', 'objectid', 'uid', 'shape_leng', 'shape_le_1', 'shape_area'];

const SearchCom = memo((props) => {
    const {map, userInfo, treeData, filterShow, featureNames, layerFields, setFilterShow, layerShow, filterDatas, setLayerShow, statisticsShow, setStatisticsShow} = props;
    const fields = layerFields?.toJS() || {};

    const [searchResultShow, setSearchResultShow] = useState(false);
    const [layerDatas, setLayerDatas] = useState([]);                   // 图层列表数据
    const [featureDatas, setFeatureDatas] = useState({});               // 要素详情数据
    const [curLayerCode, setCurLayerCode] = useState('');               // 当前操作图层code
    const [curLayerName, setCurLayerName] = useState('');               // 当前操作图层名称
    const [curUid, setCurUid] = useState('');
    const [featureDetailShow, setFeatureDetailShow] = useState(false);  // 要素详情面板显隐
    const [total, setTotal] = useState(0);
    const [loading, setLoading] = useState(false);
    const [featureLoading, setFeatureLoading] = useState(false);
    const [pageInfo, setPageInfo] = useState({page: 1, size: 20}); // 分页信息                     
    const [areaUnits, setAreaUnits] = useState();
    const [visibleFields, setVisibleFields] = useState([]);

    useEffect(() => {
        if(!map) return;
        
        if(!firstInit) {
            firstInit = true;
            return;
        }
        const pages = {page: 1, size: 20};
        setPageInfo(pages);
        search(pages, filterDatas);
    },[filterDatas, map]);

    useEffect(() => {
        firstInit = false;
        removeOverLayer();
        return () => {
            console.log(123456)
            if(map){
                removeOverLayer();
            }
            removeHighLayer();
        }
    },[]);

    useEffect(() => {
        if(!searchResultShow) {
            removeOverLayer();
            removeHighLayer();
        }
    },[searchResultShow]);

    useEffect(() => {
        if(!featureDetailShow){
            removeHighLayer();
        }
    }, [featureDetailShow]);

    // 过滤面板开启
    const openFilterPanel = () => {
        closePanel();
        setFilterShow(true);
    };

    // 图层面板开启
    const openLayerPanel = () => {
        closePanel();
        setLayerShow(true);
    };

    // 统计面板开启
    const openStatisticsPanel = () => {
        closePanel();
        setStatisticsShow(true);
    };

    // 移除图斑
    const removeOverLayer = () => {
        if (map) {
            if(pointLayer) {
                map.removeLayer(pointLayer);
                pointLayer = null;
            }
            if(polygonLayer){
                map.removeLayer(polygonLayer);
                polygonLayer = null;
            }
            // layerArr = [];
        }
    };

    // 页码变化事件
    const pageChange = useCallback((pageInfo) => {
        search(pageInfo, filterDatas);
        setPageInfo(pageInfo);
    },[filterDatas]);

    const inputChange = (e) => {
        inputValue = e.target.value;
    };

    // 搜索按钮点击事件
    const iconClick = () => {
        search();
    };

    // 获取面积单位
    const getUnits = (num) => {
        let areaUnits = {};
        let visibleFields = [];
        const cycle = (datas) => {
            datas.forEach(data => {
                const {code, children, fields} = data;
                if(code === num){
                    const {units={}, visible=''} = fields;
                    areaUnits = units;
                    visibleFields = visible.split(',');
                }else{
                    if(children.length > 0){
                        cycle(children);
                    }
                }
            })
        }

        cycle(treeData);
        setAreaUnits(areaUnits);
        setVisibleFields(visibleFields);
    };

    // 获取图斑详情
    const getFeatureDetail = async(uid, code, layerName) => {
        if(!code) return;
        layerName = layerName ? layerName : curLayerName;
        setFeatureLoading(true);
        setFeatureDetailShow(true);
        setCurUid(uid);
        setCurLayerCode(code);
        setCurLayerName(layerName);
        const params = {
            uid,
            code
        };
        // 获取面积单位
        removeHighLayer();
        getUnits(code);
        api.search.queryFeatureInfo(params)
            .then(res => {
                const {code, data} = res.data;
                if(code === 200){
                    const {geojson, ...resetData} = data;
                    const geojsonData = JSON.parse(geojson);
                    
                    if(geojsonData){
                        const {type, coordinates} = geojsonData;
                        const featureType = getType(type);
                        if(featureType === 'point'){
                            center = coordinates;
                            polygonHighLayer = L.circle([center[1], center[0]], {radius: 10}).addTo(map);
                        }
                        if(featureType === 'polygon'){
                            const pointJson = centerOfMass(polygon(geojsonData['coordinates']));
                            center = pointJson.geometry.coordinates;
                            polygonHighLayer = L.geoJSON(geojsonData, highStyleOption).addTo(map);
                        }

                        if(featureType === 'MultiPolygon'){
                            const pointJson = centerOfMass(polygon(geojsonData['coordinates'][0]));
                            center = pointJson.geometry.coordinates;
                            polygonHighLayer = L.geoJSON(geojsonData, highStyleOption).addTo(map);
                        }
                    }
                    featureLocation();
                    setFeatureDatas(resetData);
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setFeatureLoading(false);
            })


        const result = await api.search.queryFeatureInfo(params);
        const {infocode, feature=[]} = result.data;
        setFeatureLoading(false);

        if(infocode === 10000){
            // 数据过滤
            let featureData = {};
            if(feature[0]){
                Object.keys(feature[0]).forEach(key => {
                    if(!filterKeys.includes(key)){
                        featureData[key] = feature[0][key];
                    }
                    // 获取要素中心点
                    if(key === 'geojson'){
                        const {type, coordinates} = feature[0]['geojson'];
                        const featureType = getType(type);
                        if(featureType === 'point'){
                            center = coordinates;
                        }
                        if(featureType === 'polygon'){
                            const pointJson = centerOfMass(polygon(feature[0]['geojson']['coordinates']));
                            center = pointJson.geometry.coordinates;
                        }
                        if(featureType === 'MultiPolygon'){
                            const pointJson = centerOfMass(polygon(feature[0]['geojson']['coordinates'][0]));
                            center = pointJson.geometry.coordinates;
                        }
                    }
                });
            }
            
            setFeatureDatas(featureData);
        }
    };

    // 移除高亮
    const removeHighLayer = () => {
        // 移除高亮图层
        if(polygonHighLayer && map){
            map.removeLayer(polygonHighLayer);
            polygonHighLayer = null;
        }
    };

    // 获取要素类型
    const getType = (jsonType) => {
        const type = jsonType.toLocaleLowerCase();
        if (type.includes('point')) {
            return 'point';
        }

        if (type.includes('line')) {
            return 'line';
        }

        if (type.startsWith('polygon')) {
            return 'polygon';
        }

        if(type.startsWith('multipolygon')){
            return 'MultiPolygon';
        }
    };
    
    // 删除要素
    const deleteFeature = (uid=curUid, code=curLayerCode) => {
        const params = {
            code, 
            uid
        };
        api.search.deleteFeature(params)
            .then(res => {
                const {code} = res.data;
                if(code === 200){
                    setFeatureDetailShow(false);
                    message.success('图斑删除成功！');
                    search();
                }else{
                    message.error('图斑删除失败！');
                }
            }).catch(err => {
                console.log(err);
                message.error('图斑删除失败！');
            });
    };

    // 要素定位
    const featureLocation = () => {
        // console.log(center);
        // if(map && center[0] && center[1]){
        //     map.setView([center[1], center[0]]);
        // }
        if(map && polygonHighLayer){
            map.fitBounds(polygonHighLayer.getBounds());
        }
    };

    // 保存编辑要素
    const saveFeature = async (val) => {
        // const fieldsLayer = getfieldsLayer(fields);
        // const {items, itemsPrev} = getItemsAndItemsPrev(val, featureDatas, fieldsLayer);
        const params = {
            operationContent:{
                items:{...val},
                itemsPrev:{},
                operation: 'update',
                uid: curUid
            },
            operationLayer: curLayerCode ? curLayerCode : ''
        };

        console.log(curLayerName);

        api.search.saveFeature(params)
            .then(res => {
                const {code} = res.data;
                if(code === 200) {
                    message.success('提交成功！');
                    search();
                    setFeatureDetailShow(false);
                }else{
                    message.error('提交失败！');
                }
            }).catch(() => {
                message.error('提交失败！');
            });
    }

    // 搜索
    const search = (pages, datas) => {
        pages = pages ? pages : pageInfo;
        datas = datas ? datas : filterDatas;
        setLoading(true);
        closePanel();
        setSearchResultShow(true);

        // 移除图斑
        removeOverLayer();

        let params = {
            keyword: inputValue,
            ...datas,
            ...pages
        };

        // 暂时处理
        // if(params.layerName){
        //     params.layerName = params.layerName.split('-').pop();
        // }

        api.search.queryAll(params)
            .then(res => {
                const {code, data} = res.data;
                if(code === 200) {
                    const {count, result} = data;
                    setLayerDatas(result);
                    setTotal(count);
                    getJsonData(result);
                   
                }
            }).catch(err => {
                console.log(err);
            }).finally(() => {
                setLoading(false);
            });
    }

    // 搜索
    const onSearch = async() => {
        setPageInfo({page: 1, size: 20});
        search({page: 1, size: 20});
    };

    // 获取图斑json数据
    const getJsonData = async (datas) => {
        let pointFeatures = [];
        let polygonFeatures = [];
        datas.forEach((data) => {
            const { geojson, uid='', code, layerName } = data;
            if(geojson) {
                const jsonData = JSON.parse(geojson)
                if(Object.keys(jsonData).length > 0 && uid){
                    const type = getType(jsonData.type);
                    const feature = {
                        type: 'Feature',
                        geometry: jsonData,
                        properties: {
                            code: code,
                            uid: uid,
                            layerName
                        }
                    };
                    if(type === 'point'){
                        pointFeatures.push(feature);
                    }else{
                        polygonFeatures.push(feature);
                    }
                }
            }
        });
        let pointJsonData = {
            type: 'FeatureCollection',
            crs: { type: 'name', properties: { name: 'EPSG:4490' } },
            features: pointFeatures,
        };

        let polygonJsonData = {
            type: 'FeatureCollection',
            crs: { type: 'name', properties: { name: 'EPSG:4490' } },
            features: polygonFeatures,
        };

        addPointLayer(pointJsonData);
        addPolygonLayer(polygonJsonData);
    };

    // 添加点图层
    const addPointLayer = (pointJsonData) => {
        if (pointJsonData.features.length === 0) return;
        
        pointLayer = L.geoJSON(pointJsonData, {
            pointToLayer: function (feature, latlng) {
                return L.marker(latlng, {
                    icon: L.icon({
                        iconUrl: `${BASE_URL}/images/${feature.properties.code}.png`,
                        iconSize: [26, 26],
                        iconAnchor: [12, 12],
                    })
                });
            },
            onEachFeature: (feature, layer) => {
                layer.on({
                    //点击方法，变色
                    click: (e) => {
                        // 要素详情展示
                        const { properties: {code, uid, layerName }} = e.target.feature;
                        getFeatureDetail(uid, code, layerName);
                    },
                });
            },
        });
        map.addLayer(pointLayer);
        map.fitBounds(pointLayer.getBounds());
    };

    // 添加面图层
    const addPolygonLayer = (polygonJsonData) => {
        if (polygonJsonData.features.length === 0) return;

        polygonLayer = L.geoJSON(polygonJsonData, {
            style: function (feature) {
                return {
                    color: polygonColorMap[feature.properties.code] ? polygonColorMap[feature.properties.code] : 'red',
                    weight: 2,
                    opacity: 1,
                    fillColor: polygonColorMap[feature.properties.code] ? polygonColorMap[feature.properties.code] : 'red',
                    fillOpacity: 0.6,
                };
            },
            onEachFeature: (feature, layer) => {
                //对每个小块进行定义
                // layerArr.push(layer);
                layer.on({
                    //点击方法，变色
                    click: (e) => {
                        // layerArr.forEach((item) => {
                        //     polygonLayer && polygonLayer.resetStyle(item);
                        // });
                        // var layer = e.target;
                        
                        // layer.setStyle({
                        //     weight: 2,
                        //     opacity: 1,
                        //     color: 'blue',
                        //     fillOpacity: 0.6,
                        //     fillColor: 'blue',
                        // });

                        // 要素详情展示
                        const { properties: { code, uid, layerName }} = e.target.feature;
                        getFeatureDetail(uid, code, layerName);
                    },
                });
            },
        });

        map.addLayer(polygonLayer);
        map.fitBounds(polygonLayer.getBounds());
    };

    // 关闭面板
    const closePanel = () => {
        setFilterShow(false);
        setLayerShow(false);
        setStatisticsShow(false);
        setSearchResultShow(false);
        setFeatureDetailShow(false);
    };

    const filterClassName = cb({
        filterIcon: true,
        filterSelectedIcon: filterShow
    });

    const layerClassName = cb({
        layerIcon: true,
        layerSelectedIcon: layerShow
    });

    const staticticsClassName = cb({
        staticticsIcon: true,
        staticticsSelectedIcon: statisticsShow
    });

    return (
        <>
            <div className={style.searchBox}>
                <div className={style.search}>
                    <Search placeholder="输入图层、字段、地区、编码关键字" onSearch={onSearch} style={{ width: 324 }} onChange={(e) => inputChange(e)} prefix={<SearchOutlined className={style.searchIcon} onClick={iconClick}/>}/>
                </div>
                <Tooltip placement="bottom" title="图层筛选">
                    <div className={style.filter} onClick={openFilterPanel}>
                        <span className={filterClassName}>
                            <i className='iconfont icon-filter' ></i>
                        </span>
                    </div>
                </Tooltip>
                <Tooltip placement="bottom" title="图层">
                    <div className={style.layer} onClick={openLayerPanel}>
                        <span className={layerClassName}>
                            <i className='iconfont icon-layer'></i>
                        </span>
                    </div>
                </Tooltip>
                <Tooltip placement="bottom" title="统计">
                    <span className={style.statistic} onClick={openStatisticsPanel}>
                        <span className={staticticsClassName}>
                            <i className='iconfont icon-statistic'></i>
                        </span>
                    </span>
                </Tooltip>
            </div>
            {
                searchResultShow && 
                    <SearchResult 
                        userInfo={userInfo}
                        loading={loading}
                        total={total}
                        visibleFields={visibleFields}
                        pageChange={pageChange}
                        featureLoading={featureLoading}
                        layerDatas={layerDatas}
                        featureDatas={featureDatas}
                        featureNames={featureNames}
                        layerFields={layerFields}
                        fields={fields}
                        areaUnits={areaUnits}
                        featureDetailShow={featureDetailShow}
                        featureLocation={featureLocation}
                        saveFeature={saveFeature}
                        deleteFeature={deleteFeature}
                        pageInfo={pageInfo}
                        getFeatureDetail={getFeatureDetail}
                        setFeatureDetailShow={setFeatureDetailShow}
                        setSearchResultShow={setSearchResultShow}/>
            }
        </>
    )
});

SearchCom.propTypes = {
    map: PropTypes.object,
    userInfo: PropTypes.object,
    filterDatas: PropTypes.object,
    filterShow: PropTypes.bool,
    layerShow: PropTypes.bool,
    statisticsShow: PropTypes.bool,
    setFilterShow: PropTypes.func,
    setLayerShow: PropTypes.func,
    featureNames: PropTypes.object,
    layerFields: PropTypes.object,
    treeData: PropTypes.array,
    setStatisticsShow: PropTypes.func,
};

export default SearchCom;